package gk.test;

import com.alibaba.fastjson.JSON;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        // testMap2MapList();

        //testBigDecimal();

        // testNull();

        //testSplit2();

        // mapEqTest();

        // listEqTest();

        // testJson2Bean();

        // getUTCtime();

        // getD8ToUTC();

        testAddAll();


        // checkEnum();

        // testSplit();
        // testMapGetNull();
        // testNullConcat();
        // int i = pivotIndex(new int[]{1, 7, 3, 6, 5, 6});
        // System.out.println("中间下标：" + i);
    }

    private static void testAddAll() {
        List<int[]> ints = new ArrayList<>(Arrays.asList(new int[]{1, 3, 4}, new int[]{84, 1, 4}));
        List<int[]> list = new ArrayList<>(Arrays.asList(new int[]{4, 123, 3, 4}));
        ints.addAll(list);
        System.out.println(ints);
    }

    private static void getD8ToUTC() {
        // 按日分割参数
        Timestamp start = Timestamp.valueOf("2024-06-01 00:00:00");
        Timestamp end = Timestamp.valueOf("2024-06-30 00:00:00");

        // 按日分割参数
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate sLDate = start.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        LocalDate eLDate = end.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        List<String> dayList = Stream.iterate(sLDate, date -> date.plusDays(1))
                .limit(ChronoUnit.DAYS.between(sLDate, eLDate) + 1)
                .map(dtf::format)
                .collect(Collectors.toList());
        for (String date : dayList) {
            Timestamp from = Timestamp.from(ZonedDateTime.parse(date + "T00:00:00.000Z")
                    .withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
                    .toInstant());
            Timestamp to = Timestamp.from(ZonedDateTime.parse(date + "T23:59:59.999Z")
                    .withZoneSameInstant(ZoneId.of("Asia/Shanghai"))
                    .toInstant());
            System.out.println(from + " ~ " + to);

            DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            String fromMat = from.toInstant().atZone(ZoneId.of("UTC")).format(dtf2);
            String toMat = to.toInstant().atZone(ZoneId.of("UTC")).format(dtf2);
            System.out.println("UTC：" + fromMat + " ~ " + toMat);
        }
    }

    private static void getUTCtime() {
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        ZonedDateTime dateTime = ZonedDateTime.parse("2024-07-01 00:00:00", dtf.withZone(ZoneId.of("UTC")));
        ZonedDateTime utc = dateTime.withZoneSameInstant(ZoneId.of("Asia/Shanghai"));
        System.out.println(utc.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")));
    }

    private static void testJson2Bean() {
        String jsonStr = "{\"clientid\":\"OCR-bc001071b4d38672112\",\"client_date\":\"2024/08/16 13:41:06\",\"AppRunningTime\":601699353,\"AppEncrypteValue\":\"23cb0cfd02d4c87552c796891fb1a90f\",\"hdmi_usb_status\":\"true\",\"AppVer\":\"0.22\",\"MoldeName\":\"AlokaAretta70\",\"IPaddress\":\"192.168.1.11\"}";
        OcrInfo ocrInfo = JSON.parseObject(jsonStr, OcrInfo.class);
        System.out.println(ocrInfo);
    }

    private static void listEqTest() {
        List<String> l1 = new ArrayList<>();
        List<String> l2 = new LinkedList<>();
        List<String> l3 = new ArrayList<>();
        l1.add("LC1");
        l1.add("LC2");
        l2.add("LC1");
        l2.add("LC2");
        l3.add("L1");
        l3.add("L2");
        System.out.println(l1.equals(l2));
        System.out.println(l1.equals(l3));
    }

    private static void mapEqTest() {
        Map<String, String[]> map1 = new HashMap<>();
        map1.put("a", new String[]{"MI", "MC"});

        Map<String, String[]> map2 = new HashMap<>();
        map2.put("a", new String[]{"MI", "MC"});

        Map<String, String[]> map3 = new HashMap<>();
        map3.put("a", new String[]{"MI"});
        System.out.println(map1.equals(map2));
        System.out.println(map1.equals(map3));

        boolean eEq = map1.entrySet().stream().allMatch(e -> map2.containsKey(e.getKey()) && Arrays.equals(e.getValue(), map2.get(e.getKey())));
        System.out.println(eEq);
    }

    private static void testSplit2() {
        String s = "abc/";
        String s1 = "/efg";
        String[] split = s.split("/");
        System.out.println(split[0]);
        //System.out.println(split[1]);

        String[] split1 = s1.split("/");
        System.out.println(split1[0].getClass());
        System.out.println(split1[1]);
    }

    private static void testNull() {
        ConcurrentHashMap<String, ChangeStatus> last = new ConcurrentHashMap<>();
        last.put("a", null);
        last.put("b", null);
        last.put("c", null);
        if (null != last.get("a")) {
            System.out.println("true");
        } else {
            System.out.println("false");
        }
    }

    private static void testBigDecimal() {
        Map<String, Float> testValue = new HashMap<>();
        testValue.put("k1", 1.2f);
        BigDecimal value = BigDecimal.valueOf(testValue.get("k2"));
        System.out.println(value);
    }

    private static void checkEnum() {
        ChangeStatus run = ChangeStatus.valueOf("RUN");
        System.out.println(ChangeStatus.RUN == run);
        System.out.println(run);
    }

    private static void testNullConcat() {
        String value = null;
        System.out.println(value + ":" + System.currentTimeMillis());
    }

    private static void testMapGetNull() {
        Map<String, Object> map = new HashMap<>(2);
        System.out.println(map.get("id"));
    }

    private static void testSplit() {
        String[] split = "abc".split(":");
        System.out.println(Arrays.toString(split));
    }

    private static void testMap2MapList() {
        List<HashMap<String, Object>> list = Arrays.asList(
                new HashMap<String, Object>() {{
                    put("device_address", "123");
                    put("id", 1);
                    put("comparison_type", "ABC");
                }},
                new HashMap<String, Object>() {{
                    put("device_address", "456");
                    put("id", 1);
                    put("comparison_type", "ABC");
                }},
                new HashMap<String, Object>() {{
                    put("device_address", "123");
                    put("id", 1);
                    put("comparison_type", "CDA");
                }}
        );
        Map<Object, List<Object>> collect = list.stream().collect(Collectors.groupingBy(
                map -> map.get("device_address"),
                Collectors.mapping(
                        map -> map.get("comparison_type"),
                        Collectors.toList()
                )));
        System.out.println(collect);
    }

    /**
     * 题目：找出数组中一个index，其左侧元素之和 等于 右侧元素之和
     * 本质：数组中所有元素之和，找到一个index，其左边是总和的一半，那么其右边自然就是总和的另一半
     * 思路：求出数组总和，循环累计当前index的左边元素值，并判断是否达到总和的一半。达到：找到这个index，并return
     * 注意：左边元素之和，与右边元素之和 相等，所以判断时，总和中要去掉当前元素值
     *
     * @param nums
     * @return
     */
    public static int pivotIndex(int[] nums) {
        int total = Arrays.stream(nums).sum();
        int leftSum = 0;
        for (int i = 0; i < nums.length; i++) {
            // 判断左侧元素之和的2倍是否等于总和，注意要减去当前元素值。
            // 本质就是：左侧元素之和 == （总和/2）- 不参与计算的当前元素值。即：当前元素的 左侧之和 == 右侧之和
            if (2 * leftSum == total - nums[i]) {
                return i;
            }
            // 这里利用后置累加，实现只判定当前idx左侧元素之和
            leftSum += nums[i];
        }
        return -1;
    }


    public static int[] twoSum(int[] nums, int target) {
        for (int i = 0; i < nums.length; i++) {
            int daf = target - nums[i];
            for (int i1 = i + 1; i1 < nums.length; i1++) {
                if (nums[i1] == daf) {
                    return new int[]{i, i1};
                }
            }
        }
        return null;
    }

    public static int[] twoSum2(int[] nums, int target) {
        Map<Integer, Integer> hashMap = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            Integer integer = hashMap.get(target - nums[i]);
            if (null != integer) {
                return new int[]{integer, i};
            }
            hashMap.put(nums[i], i);
        }
        return null;
    }
}